﻿#region Usings

using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using XPressify.Data.Helpers;
using XPressify.Models;
using XPressify.Data;

#endregion

namespace XPressify.Controllers
{
    public class SearchController : BaseController
    {
        [HttpPost]
        public ActionResult Search(SearchModel model)
        {
            var currentUser = CurrentUser;
            
            var blockedFriends =                            // all users that are blocked
                Repository.AsQueryable<Relationship>().Where(
                    rel =>
                    (rel.BaseSubject.Id == currentUser.Id || rel.BaseSubject2.Id == currentUser.Id) &&
                    rel.RelationType == RelationshipType.FriendOf && rel.Status == RelationshipStatus.Blocked);

            //all users found except blocked one
            var foundUserSubjects =
                Repository.AsQueryable<User>().Where(
                    user =>
                    user.Id != currentUser.Id &&
                    (user.FirstName.ToLower().StartsWith(model.SearchText.ToLower()) ||
                     user.LastName.ToLower().StartsWith(model.SearchText.ToLower()) ||
                     user.Email.ToLower().StartsWith(model.SearchText.ToLower())) && !blockedFriends.Any(
                         bl => (bl.BaseSubject.Id == user.Id || bl.BaseSubject2.Id == user.Id)));

            var foundGroupSubjects = Repository.AsQueryable<Group>().Where(gr => gr.Name.ToLower().Contains(model.SearchText.ToLower()));
            var foundPageSubjects = Repository.AsQueryable<Page>().Where(pg => pg.Name.ToLower().Contains(model.SearchText.ToLower()));
            var foundEventSubjects = Repository.AsQueryable<Event>().Where(ev => ev.Name.ToLower().Contains(model.SearchText.ToLower()));

            var subjects = new List<FoundSubject>();

            foreach (var foundUser in foundUserSubjects)
            {
                // get friend relationship if exist
                var friendRelationships = Repository.AsQueryable<Relationship>().SingleOrDefault(
                    rel =>
                    ((rel.BaseSubjectId == currentUser.Id && rel.BaseSubjectId2 == foundUser.Id) ||
                     (rel.BaseSubjectId2 == currentUser.Id && rel.BaseSubjectId == foundUser.Id)) &&
                    rel.RelationType == RelationshipType.FriendOf);
                //if true it will show confirm friend button
                var confirmButton = false;
                if(friendRelationships != null && 
                   friendRelationships.BaseSubject2.Id == currentUser.Id &&
                   (friendRelationships.Status == RelationshipStatus.Postponed || 
                    friendRelationships.Status == RelationshipStatus.Requested))
                {
                    confirmButton = true;
                }
                var newFoundSubject = new FoundSubject()
                                          {
                                              Relationship = friendRelationships,
                                              SubjectType = SubjectType.User,
                                              SubjectId = foundUser.Id,
                                              SubjectFullname = foundUser.FullName,
                                              SubjectPicturePath = Repository.GetProfilePicturePath(foundUser.Id),
                                              ConfirmButton = confirmButton
                                          };
                subjects.Add(newFoundSubject);

            }
            foreach (var foundEvent in foundEventSubjects)
            {
                // get member or administrator relationship if exist
                var relationships = Repository.AsQueryable<Relationship>().SingleOrDefault(
                    rel =>
                    (rel.BaseSubjectId == currentUser.Id && rel.BaseSubjectId2 == foundEvent.Id) &&
                    (rel.RelationType == RelationshipType.MemberOf ||
                     rel.RelationType == RelationshipType.AdministratorOf));

                //if not member or admin then private events will not show
                if(relationships == null && foundEvent.PrivacyType == SubjectPrivacy.Private)
                {
                    continue;
                }

                //try to find cover picture of event album if exist
                var coverPicture =
                    Repository.AsQueryable<Media>().SingleOrDefault(
                        med => med.IsCover && med.Album.BaseSubject.Id == foundEvent.Id);
                var subjectPicturePath = "";
                if(coverPicture != null)
                {
                    subjectPicturePath = "/Media/" + foundEvent.Id + "/" + coverPicture.Album.Id + "/" + coverPicture.Id + "." + coverPicture.FileType;
                }

                //if true it will show confirm friend button
                var confirmButton = false;
                if (relationships != null &&
                   relationships.BaseSubject.Id == currentUser.Id &&
                   (relationships.Status == RelationshipStatus.Postponed ||
                    relationships.Status == RelationshipStatus.Requested))
                {
                    confirmButton = true;
                }

                var newFoundSubject = new FoundSubject()
                {
                    Relationship = relationships,
                    SubjectType = SubjectType.Event,
                    SubjectId = foundEvent.Id,
                    SubjectFullname = foundEvent.FullName,
                    SubjectPicturePath = subjectPicturePath,
                    ConfirmButton = confirmButton
                };
                subjects.Add(newFoundSubject);
            }
            foreach (var foundGroup in foundGroupSubjects)
            {
                // get member or administrator relationship if exist
                var relationships = Repository.AsQueryable<Relationship>().SingleOrDefault(
                    rel =>
                    (rel.BaseSubjectId == currentUser.Id && rel.BaseSubjectId2 == foundGroup.Id) &&
                    (rel.RelationType == RelationshipType.MemberOf ||
                     rel.RelationType == RelationshipType.AdministratorOf));

                //if not member or admin then private events will not show
                if (relationships == null && foundGroup.PrivacyType == SubjectPrivacy.Private)
                {
                    continue;
                }

                //try to find cover picture of event album if exist
                var coverPicture =
                    Repository.AsQueryable<Media>().SingleOrDefault(
                        med => med.IsCover && med.Album.BaseSubject.Id == foundGroup.Id);
                var subjectPicturePath = "";
                if (coverPicture != null)
                {
                    subjectPicturePath = "/Media/" + foundGroup.Id + "/" + coverPicture.Album.Id + "/" + coverPicture.Id + "." + coverPicture.FileType;
                }

                //if true it will show confirm friend button
                var confirmButton = false;
                if (relationships != null &&
                   relationships.BaseSubject.Id == currentUser.Id &&
                   (relationships.Status == RelationshipStatus.Postponed ||
                    relationships.Status == RelationshipStatus.Requested))
                {
                    confirmButton = true;
                }

                var newFoundSubject = new FoundSubject()
                {
                    Relationship = relationships,
                    SubjectType = SubjectType.Group,
                    SubjectId = foundGroup.Id,
                    SubjectFullname = foundGroup.FullName,
                    SubjectPicturePath = subjectPicturePath,
                    ConfirmButton = confirmButton
                };
                subjects.Add(newFoundSubject);
            }
            foreach (var foundPage in foundPageSubjects)
            {
                // get member or administrator relationship if exist
                var relationships = Repository.AsQueryable<Relationship>().SingleOrDefault(
                    rel =>
                    (rel.BaseSubjectId == currentUser.Id && rel.BaseSubjectId2 == foundPage.Id) &&
                    (rel.RelationType == RelationshipType.MemberOf ||
                     rel.RelationType == RelationshipType.AdministratorOf));

                //if not member or admin then private events will not show
                if (relationships == null && foundPage.PrivacyType == SubjectPrivacy.Private)
                {
                    continue;
                }

                //try to find cover picture of event album if exist
                var coverPicture =
                    Repository.AsQueryable<Media>().SingleOrDefault(
                        med => med.IsCover && med.Album.BaseSubject.Id == foundPage.Id);
                var subjectPicturePath = "";
                if (coverPicture != null)
                {
                    subjectPicturePath = "/Media/" + foundPage.Id + "/" + coverPicture.Album.Id + "/" + coverPicture.Id + "." + coverPicture.FileType;
                }

                //if true it will show confirm friend button
                var confirmButton = false;
                if (relationships != null &&
                   relationships.BaseSubject.Id == currentUser.Id &&
                   (relationships.Status == RelationshipStatus.Postponed ||
                    relationships.Status == RelationshipStatus.Requested))
                {
                    confirmButton = true;
                }

                var newFoundSubject = new FoundSubject()
                {
                    Relationship = relationships,
                    SubjectType = SubjectType.Page,
                    SubjectId = foundPage.Id,
                    SubjectFullname = foundPage.FullName,
                    SubjectPicturePath = subjectPicturePath,
                    ConfirmButton = confirmButton
                };
                subjects.Add(newFoundSubject);
            }



            var searchResultsModel = new SearchResulstsModel {FoundSubjects = subjects};
            return PartialView("SearchResults", searchResultsModel);
        }

        public ActionResult SearchResults(SearchResulstsModel model)
        {
            return View(model);
        }
    }
}